#include<bits/stdc++.h>
#define ls (x<<1)
#define rs (x<<1|1)
using namespace std;
const int N=2e5+5;
int n,a[N],b[N],vis[N],cnt,d[N],op[N],nxt[N],ans;
struct tree{
	int l,r;
	pair<int,int> maxn;
}c[N<<2];
//num,id
pair<int,int> MX(pair<int,int> a,pair<int,int> b){
	if(a.first==b.first){
		if(a.second>b.second) return a;
		return b;
	}
	if(a.first>b.first) return a;
	return b;
}
inline void pushup(int x){
	c[x].maxn=MX(c[ls].maxn,c[rs].maxn);
}
void build(int x,int l,int r){
	c[x].l=l,c[x].r=r;
	if(l==r){
		c[x].maxn={0,0};
		return;
	}
	int mid=(l+r)>>1;
	build(ls,l,mid),build(rs,mid+1,r);
	pushup(x);
}
void upd(int x,int id,int k){
	if(c[x].l==c[x].r){
		c[x].maxn={k,b[id]};
		return;
	}
	int mid=(c[x].l+c[x].r)>>1;
	id<=mid?upd(ls,id,k):upd(rs,id,k);
	pushup(x);
}
pair<int,int> qry(int x,int l,int r){
	if(l>r) return {0,0};
	if(c[x].l>=l&&c[x].r<=r) return c[x].maxn;
	int mid=(c[x].l+c[x].r)>>1;pair<int,int> ans={0,0};
	if(l<=mid) ans=MX(ans,qry(ls,l,r));
	if(r>mid) ans=MX(ans,qry(rs,l,r));
	return ans;
}
int G;
signed main() {
	freopen("shung.in","r",stdin);
	freopen("shung.out","w",stdout);
	ios::sync_with_stdio(false);
	cin.tie(0);
	cout.tie(0);
	cin>>n;
	for(int i=1;i<=n;i++) cin>>a[i],a[i]=n+1-a[i],b[a[i]]=i;
	build(1,1,n+1);
	for(int i=n;i>=1;i--){
		pair<int,int> tlh=qry(1,a[i]+1,n+1);
		int num=tlh.first,id=tlh.second;
		upd(1,a[i],num+1);nxt[i]=id;
	}
	ans=qry(1,a[1],a[1]).first;
	int x=1,aya;
	while(x) vis[x]=1,x=nxt[x];
	for(int i=1;i<=n;i++){
		if(!vis[i]) ++cnt,d[cnt]=a[i],op[cnt]=(aya<a[i]);
		else aya=a[i];
	}
	int minn=n+1,lst=0;
	build(1,1,n+1);
	for(int i=1;i<=cnt;i++){
		if(!op[i]){
			if(d[i]<minn) upd(1,d[i],qry(1,d[i]+1,minn).first+1),minn=d[i];
		}
		else upd(1,d[i],qry(1,d[i]+1,minn).first+1);
	}
 	G=qry(1,1,n).first+ans;
	cnt=0;memset(vis,0,sizeof(vis));memset(nxt,0,sizeof(nxt));
	memset(d,0,sizeof(d));memset(op,0,sizeof(op));
	for(int i=1;i<=n;i++) a[i]=n+1-a[i],b[a[i]]=i;
	build(1,1,n+1);
	for(int i=n;i>=1;i--){
		pair<int,int> tlh=qry(1,a[i]+1,n+1);
		int num=tlh.first,id=tlh.second;
		upd(1,a[i],num+1);nxt[i]=id;
	}
	ans=qry(1,a[1],a[1]).first;
	x=1;
	while(x) vis[x]=1,x=nxt[x];
	for(int i=1;i<=n;i++){
		if(!vis[i]) ++cnt,d[cnt]=a[i],op[cnt]=(aya>a[i]);
		else aya=a[i];
	}
	minn=n+1,lst=0;
	build(1,1,n+1);
	for(int i=1;i<=cnt;i++){
		if(!op[i]){
			if(d[i]<minn) upd(1,d[i],qry(1,d[i]+1,minn).first+1),minn=d[i];
		}
		else upd(1,d[i],qry(1,d[i]+1,minn).first+1);
	}
	cout<<max(G,qry(1,1,n).first+ans);
	return 0;
}
